package com.zdsoft.finance.common.base.impl;

import com.zdsoft.finance.common.base.CustomRepository;
import com.zdsoft.finance.common.base.QueryObj;
import com.zdsoft.framework.core.common.domain.BaseEntity;
import com.zdsoft.framework.core.common.page.Page;
import com.zdsoft.framework.core.common.page.PageImpl;
import com.zdsoft.framework.core.common.page.Pageable;
import com.zdsoft.framework.core.common.util.ObjectHelper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaEntityInformationSupport;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 自定义操作仓库实现类
 * 
 * @author LiaoGuoWei
 * @create 2016-10-27 10:13
 **/
@NoRepositoryBean
public class CustomRepositoryImpl<T extends BaseEntity, ID extends Serializable> extends SimpleJpaRepository<T, ID>
		implements CustomRepository<T, ID> {
	static Logger logger = LoggerFactory.getLogger(CustomRepositoryImpl.class);
	private final EntityManager entityManager;

	public CustomRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
		super(entityInformation, entityManager);
		this.entityManager = entityManager;
	}

	public CustomRepositoryImpl(Class<T> domainClass, EntityManager em) {
		this(JpaEntityInformationSupport.getEntityInformation(domainClass, em), em);
	}

	@Override
	public List<T> findByHql(String hql, Map<String, Object> condition) {
		// 获得query对象
		Query q = entityManager.createQuery(hql);
		// 将查询条件注入HQL语句中
		for (Serializable key : condition.keySet()) {
			q.setParameter(key.toString(), condition.get(key));
		}
		// 执行查询
		List<T> sourceData = (List<T>) q.getResultList();
		return sourceData;
	}

	@Override
	public Page<T> findByHqlPage(Pageable pageable, String hql, Map<String, Object> condition) {
		if (pageable == null) {
			throw new IllegalArgumentException("pageable 不能为空!");
		}
		// 申明分页数据
		Page<T> pager = new PageImpl<T>(pageable);
		// 创建query
		Query q = entityManager.createQuery(hql);
		// 设置查询条件
		for (Serializable key : condition.keySet()) {
			q.setParameter(key.toString(), condition.get(key));
		}
		q.setFirstResult((pageable.getPage() - 1) * pageable.getRows());
		q.setMaxResults(pageable.getRows());
		pager.setRecords(q.getResultList());
		pager.setTotalRows(this.countAll(hql, condition));
		return pager;
	}

	@Override
	public Page<T> findByHqlConditions(Pageable pageable, final List<QueryObj> li) {
		Specification<T> specification = new Specification<T>() {
			
			
			@Override
			public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> predicates = new ArrayList<Predicate>();

				predicates.add(cb.equal((root.get("isDeleted")).as(Boolean.class), false));

				if (ObjectHelper.isNotEmpty(li)) {
					for (QueryObj obj : li) {
						if ("R".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "Integer":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.gt((root.get(objArray[0]).get(objArray[1])).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.gt((root.get(obj.getObj())).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								}

								break;
							case "BigDecimal":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.gt((root.get(objArray[0]).get(objArray[1])).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								} else {
									predicates.add(cb.gt((root.get(obj.getObj())).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								}

								break;
							case "Double":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.gt((root.get(objArray[0]).get(objArray[1])).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.gt((root.get(obj.getObj())).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								}
								break;
							case "Float":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.gt((root.get(objArray[0]).get(objArray[1])).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.gt((root.get(obj.getObj())).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								}
								break;
							case "Long":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.gt((root.get(objArray[0]).get(objArray[1])).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.gt((root.get(obj.getObj())).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								}
								break;
							case "Date":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates
											.add(cb.greaterThan((root.get(objArray[0]).get(objArray[1])).as(Date.class),
													(Date) obj.getValue()));
								} else {
									predicates.add(cb.greaterThan(root.get(obj.getObj()).as(Date.class),
											(Date) obj.getValue()));
								}
								break;
							default:
								break;
							}
						} else if ("RE".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "Integer":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.greaterThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.greaterThanOrEqualTo((root.get(obj.getObj())).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								}
								break;
							case "BigDecimal":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.greaterThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								} else {
									predicates
											.add(cb.greaterThanOrEqualTo((root.get(obj.getObj())).as(BigDecimal.class),
													new BigDecimal(obj.getValue().toString())));
								}
								break;
							case "Double":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.greaterThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.greaterThanOrEqualTo((root.get(obj.getObj())).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								}
								break;
							case "Float":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.greaterThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.greaterThanOrEqualTo((root.get(obj.getObj())).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								}
								break;
							case "Long":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.greaterThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.greaterThanOrEqualTo((root.get(obj.getObj())).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								}
								break;
							case "Date":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.greaterThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Date.class),
											(Date) obj.getValue()));
								} else {
									predicates.add(cb.greaterThanOrEqualTo(root.get(obj.getObj()).as(Date.class),
											(Date) obj.getValue()));
								}
								break;
							default:
								break;
							}
						} else if ("L".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "Integer":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lt((root.get(objArray[0]).get(objArray[1])).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lt((root.get(obj.getObj())).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								}
								break;
							case "BigDecimal":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lt((root.get(objArray[0]).get(objArray[1])).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								} else {
									predicates.add(cb.lt((root.get(obj.getObj())).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								}
								break;
							case "Double":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lt((root.get(objArray[0]).get(objArray[1])).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lt((root.get(obj.getObj())).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								}
								break;
							case "Float":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lt((root.get(objArray[0]).get(objArray[1])).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lt((root.get(obj.getObj())).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								}
								break;
							case "Long":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lt((root.get(objArray[0]).get(objArray[1])).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lt((root.get(obj.getObj())).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								}
								break;
							case "Date":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThan((root.get(objArray[0]).get(objArray[1])).as(Date.class),
											(Date) obj.getValue()));
								} else {
									predicates.add(
											cb.lessThan(root.get(obj.getObj()).as(Date.class), (Date) obj.getValue()));
								}
								break;
							default:
								break;
							}
						} else if ("LE".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "Integer":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lessThanOrEqualTo((root.get(obj.getObj())).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								}
								break;
							case "BigDecimal":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								} else {
									predicates.add(cb.lessThanOrEqualTo((root.get(obj.getObj())).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								}
								break;
							case "Double":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lessThanOrEqualTo((root.get(obj.getObj())).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								}
								break;
							case "Float":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lessThanOrEqualTo((root.get(obj.getObj())).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								}
								break;
							case "Long":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.lessThanOrEqualTo((root.get(obj.getObj())).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								}
								break;
							case "Date":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.lessThanOrEqualTo(
											(root.get(objArray[0]).get(objArray[1])).as(Date.class),
											(Date) obj.getValue()));
								} else {
									predicates.add(cb.lessThanOrEqualTo(root.get(obj.getObj()).as(Date.class),
											(Date) obj.getValue()));
								}
								break;
							default:
								break;
							}
						} else if ("E".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "Integer":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								}
								break;
							case "BigDecimal":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates
											.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(BigDecimal.class),
													new BigDecimal(obj.getValue().toString())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								}
								break;
							case "Double":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								}
								break;
							case "Float":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								}
								break;
							case "Long":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								}
								break;
							case "String":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(String.class),
											String.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(String.class),
											String.valueOf(obj.getValue().toString())));
								}
								break;
							case "Date":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(Date.class),
											(Date) (obj.getValue())));
								} else {
									predicates.add(
											cb.equal((root.get(obj.getObj())).as(Date.class), (Date) (obj.getValue())));
								}
								break;
							case "Boolean":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.equal((root.get(objArray[0]).get(objArray[1])).as(Boolean.class),
											(Boolean) (obj.getValue())));
								} else {
									predicates.add(cb.equal((root.get(obj.getObj())).as(Boolean.class),
											(Boolean) (obj.getValue())));
								}
							default:
								break;
							}
						} else if ("NE".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "Integer":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates
											.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(Integer.class),
													Integer.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(Integer.class),
											Integer.valueOf(obj.getValue().toString())));
								}
								break;
							case "BigDecimal":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(
											cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(BigDecimal.class),
													new BigDecimal(obj.getValue().toString())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(BigDecimal.class),
											new BigDecimal(obj.getValue().toString())));
								}
								break;
							case "Double":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates
											.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(Double.class),
													Double.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(Double.class),
											Double.valueOf(obj.getValue().toString())));
								}
								break;
							case "Float":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(Float.class),
											Float.valueOf(obj.getValue().toString())));
								}
								break;
							case "Long":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(Long.class),
											Long.valueOf(obj.getValue().toString())));
								}
								break;
							case "String":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates
											.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(String.class),
													String.valueOf(obj.getValue().toString())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(String.class),
											String.valueOf(obj.getValue().toString())));
								}
								break;
							case "Date":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(Date.class),
											(Date) (obj.getValue())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(Date.class),
											(Date) (obj.getValue())));
								}
								break;
							case "Boolean":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates
											.add(cb.notEqual((root.get(objArray[0]).get(objArray[1])).as(Boolean.class),
													(Boolean) (obj.getValue())));
								} else {
									predicates.add(cb.notEqual((root.get(obj.getObj())).as(Boolean.class),
											(Boolean) (obj.getValue())));
								}
								break;
							default:
								break;
							}
						} else if ("LK".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "String":
								if (obj.getObj().indexOf(".") != -1) {
									String[] objArray = obj.getObj().split("\\.");
									predicates.add(cb.like((root.get(objArray[0]).get(objArray[1])).as(String.class),
											("%" + obj.getValue().toString() + "%")));
								} else {
									predicates.add(cb.like((root.get(obj.getObj())).as(String.class),
											("%" + obj.getValue().toString() + "%")));
								}
								break;
							default:
								break;
							}
						} else if ("IN".equals(obj.getOperator())) {
							List<Object> queryList = (List<Object>) obj.getValue();
							if (obj.getObj().indexOf(".") != -1) {
								String[] objArray = obj.getObj().split("\\.");
								Expression<Object> exp = root.get(objArray[0]).get(objArray[1]);
								predicates.add(exp.in(queryList));
							} else {
								Expression<Object> exp = root.get(obj.getObj());
								predicates.add(exp.in(queryList));
							}
						} else if ("NN".equals(obj.getOperator())) {
							List<Object> queryList = (List<Object>) obj.getValue();
							if (obj.getObj().indexOf(".") != -1) {
								String[] objArray = obj.getObj().split("\\.");
								Expression<Object> exp = root.get(objArray[0]).get(objArray[1]);
								predicates.add(exp.in(queryList).not());
							} else {
								Expression<Object> exp = root.get(obj.getObj());
								predicates.add(exp.in(queryList).not());
							}

						} else if ("OL".equals(obj.getOperator())) {
							switch (obj.getElement()) {
							case "String":
								List<Predicate> newPredicates = new ArrayList<Predicate>();
								List<Object> conditions = (List<Object>) obj.getValue();
								for (Object objs : conditions) {
									if (obj.getObj().indexOf(".") != -1) {
										String[] objArray = obj.getObj().split("\\.");
										newPredicates
												.add(cb.like((root.get(objArray[0]).get(objArray[1])).as(String.class),
														("%" + objs.toString() + "%")));
									} else {
										newPredicates.add(cb.like((root.get(obj.getObj())).as(String.class),
												("%" + objs.toString() + "%")));
									}

								}
								Predicate predocate = cb.or(newPredicates.toArray(new Predicate[newPredicates.size()]));
								predicates.add(predocate);
								break;
							default:
								break;
							}
						} else if ("BT".equals(obj.getOperator())) {
							String[] times = obj.getValue().toString().split(",");
							if (ObjectHelper.isNotEmpty(times)) {
								if (ObjectHelper.isNotEmpty(times[0])) {
									if (obj.getObj().indexOf(".") != -1) {
										String[] objArray = obj.getObj().split("\\.");
										predicates.add(cb.greaterThanOrEqualTo(
												(root.get(objArray[0]).get(objArray[1])).as(Long.class),
												Long.valueOf(times[0])));
									} else {
										predicates.add(cb.greaterThanOrEqualTo((root.get(obj.getObj())).as(Long.class),
												Long.valueOf(times[0])));
									}

								}
								if (times.length > 1 && ObjectHelper.isNotEmpty(times[1])) {
									if (obj.getObj().indexOf(".") != -1) {
										String[] objArray = obj.getObj().split("\\.");
										predicates.add(cb.lessThanOrEqualTo(
												(root.get(objArray[0]).get(objArray[1])).as(Long.class),
												Long.valueOf(times[1])));
									} else {
										predicates.add(cb.lessThanOrEqualTo((root.get(obj.getObj())).as(Long.class),
												Long.valueOf(times[1])));
									}

								}
							}
						}
					}
				}
				query.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));

				return query.getRestriction();
			}

		};
		org.springframework.data.domain.Pageable springPageable = new PageRequest(pageable.getPage() - 1,
				pageable.getRows());
		org.springframework.data.domain.Page<T> pages = super.findAll(specification, springPageable);
		Page<T> zdPage = new PageImpl<T>(pageable);
		zdPage.setRecords(pages.getContent());
		zdPage.setTotalRows(pages.getTotalElements());
		return zdPage;
	}

	@Override
	public Long countAll(String hql, Map<String, Object> condition) {
		if (hql == null) {
			return 0l;
		}
		String tmpHql = hql.toLowerCase();
		hql = "select count(*) " + hql.substring(tmpHql.indexOf("from"));
		logger.debug("count(*) hql ---->" + hql);
		// 创建query
		Query q = entityManager.createQuery(hql);
		// 设置查询条件
		for (Serializable key : condition.keySet()) {
			q.setParameter(key.toString(), condition.get(key));
		}
		Long result = (Long) q.getResultList().get(0);
		return result;
	}

	@Override
	@Transactional
	public T saveEntity(T t) {
		t.setCreateTime(new Date());
		t.setIsDeleted(false);
		return this.saveAndFlush(t);
	}

	@Override
	@Transactional
	public T updateEntity(T t) {
		t.setUpdateTime(new Date());
		t.setIsDeleted(false);
		return this.saveAndFlush(t);
	}

	@Override
	public T logicDelete(T t) {
		t.setDeleteTime(new Date());
		t.setIsDeleted(true);
		return this.entityManager.merge(t);
	}
}
